#!/bin/bash

# 获取公网IP地址的增强版脚本（国内环境优化）

# 颜色定义
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
RESET='\033[0m'

# ---------------------- IP获取方法 ----------------------

# 方法1：使用 cURL 访问 ip.sb
get_public_ip_curl() {
    curl -s --connect-timeout 3 --retry 2 ip.sb
}

# 方法2：使用 wget 访问 ip.3322.net
get_public_ip_wget() {
    wget -qO- --timeout=3 --tries=2 http://ip.3322.net/ | 
        grep -oP '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | 
        head -n1  # 确保只取第一个匹配项
}

# 方法3：使用 cURL 访问 cip.cc 并提取 IP
get_public_ip_cipcc() {
    curl -s --connect-timeout 3 --retry 2 cip.cc | 
        grep -oP 'IP\s+:\s+\K[\d.]+'
}

# 方法4：使用 myip.ipip.net 提取 IP
get_public_ip_ipip() {
    curl -s --connect-timeout 3 --retry 2 http://myip.ipip.net | 
        grep -oP '(?<=当前 IP：)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
}

# 方法5：icanhazip（国际备用）
get_public_ip_icanhazip() {
    curl -s --connect-timeout 5 --retry 2 icanhazip.com
}

# 方法6：httpbin.org（JSON解析）
get_public_ip_httpbin() {
    curl -s --connect-timeout 3 http://httpbin.org/ip | 
        grep -oP 'origin": "\K[\d.]+'
}

# ---------------------- 核心逻辑 ----------------------

# 清洗IP数据（过滤无效地址）
clean_ip() {
    echo "$1" | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' |
        grep -vE '^(127\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.)'
}

# 主函数
main() {
    echo -e "${BLUE}正在测试获取公网 IP 的方法（共6种）...${RESET}"

    # 方法列表（名称+命令）
    declare -A methods=(
        ['1. ip.sb (cURL)']="get_public_ip_curl"
        ['2. ip.3322 (wget)']="get_public_ip_wget"
        ['3. cip.cc']="get_public_ip_cipcc"
        ['4. myip.ipip']="get_public_ip_ipip"
        ['5. icanhazip']="get_public_ip_icanhazip"
        ['6. httpbin']="get_public_ip_httpbin"
    )

    # 结果收集
    declare -A results
    for name in "${!methods[@]}"; do
        cmd="${methods[$name]}"
        result=$($cmd)
        clean_result=$(clean_ip "$result")
        if [ -n "$clean_result" ]; then
            results[$name]="$clean_result"
            echo -e "  ${GREEN}✓${RESET} $name -> ${GREEN}$clean_result${RESET}"
        else
            results[$name]="获取失败"
            echo -e "  ${RED}✗${RESET} $name -> ${RED}请求超时或无效数据${RESET}"
        fi
    done

    # 统计有效IP
    unique_ips=($(printf "%s\n" "${results[@]}" | 
        grep -v '获取失败' | sort | uniq))
    valid_count=$(printf "%s\n" "${results[@]}" | grep -v '获取失败' | wc -l)

    # 结果分析
    echo -e "\n${BLUE}===== 统计结果 =====${RESET}"
    echo -e "有效结果：${valid_count}/6"
    echo -e "唯一IP列表：${unique_ips[*]}"

    if [ ${#unique_ips[@]} -eq 1 ]; then
        echo -e "\n${GREEN}✔ 一致性验证通过：公网IP为 ${unique_ips[0]}${RESET}"
    elif [ ${#unique_ips[@]} -gt 1 ]; then
        echo -e "\n${YELLOW}⚠ 检测到多个不同IP：${RESET}"
        for ip in "${unique_ips[@]}"; do
            services=$(for key in "${!results[@]}"; do 
                [[ "${results[$key]}" == "$ip" ]] && echo "$key"
            done | tr '\n' ',')
            echo -e "  - ${YELLOW}$ip${RESET} (来自：${services%,})"
        done
        echo -e "\n${RED}可能原因："
        echo "1. 网络存在多出口负载均衡"
        echo "2. 部分服务返回代理服务器IP"
        echo "3. 临时DNS解析差异${RESET}"
    else
        echo -e "\n${RED}✗ 所有方法均失败，请检查网络连接！${RESET}"
    fi
}

# 执行主函数
main